//
//  main.cpp
//  STL
//
//  Created by ryu on 2021/10/13.
//

#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
#include <set>
void test();
void test2();
void test3();
void test4();
void test5();
void test6();
void test7();
void MyPrint(int val);


using namespace std;


class People{
    friend ostream& operator<<(ostream& out, People& p);
public:
    string name;
    int age;
    People(string name,int age){
        this->name = name;
        this->age = age;
    }
};

void p_swap(People *p1,People *p2){
    People *p = NULL;
    p = p1;
    p1 = p2;
    p2 = p;
}

int main(int argc, const char * argv[]) {
    // insert code here...
//    std::cout << "Hello, World!\n";
//    test();
//    test2();
//    test3();
//    test4();
//    test5();
//    test6();
    test7();
    return 0;
}


void MyPrint(int val)
{
    cout << val << endl;
}

//c++和java不一样，即便是“对象”类型传递还是需要使用引用作为参数
//需要形参(指针变量)指向实参变量单元
void printVector(vector<int> &v){
    for_each(v.begin(), v.end(), MyPrint);
//    v.push_back(2);
}

//vector存放内置数据类型
void test(){
    
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    v.push_back(5);
    
    //begin和end返回指针
    vector<int>::iterator pBegin = v.begin();
    vector<int>::iterator pEnd = v.end();
    
    
//    while(pBegin != pEnd){
//        cout << *pBegin << endl;
//
//        pBegin++;
//    }
    
    //使用STL提供标准遍历算法  头文件 algorithm
    for_each(v.begin(), v.end(), MyPrint);
};

//指针测试
void test2(){
    int a = 10;
    int *p;
    p = &a;
    
    cout<<*p<<endl;
    People p1("ryu",16);
    People *p2 = new People("孙悟空",100);
    People *p3 = new People("猪八戒",80);
    
    //指针所占用的内存大小
    cout << sizeof(p2) << endl;
    cout << sizeof(p) << endl;
    
    cout << sizeof(People) << endl; //32 = 24(string) + 8
    
    p_swap(p2, p3);
    
    cout << p2->name << endl;
    cout << p3->name << endl;
    
    string str1 = "abcdefgde";
    str1.replace(1, 3, "1111");

    cout << "str1 = " << str1 << endl;
}

//vector容器 构建vector的一些构造
void test3(){
    vector<int> v;
    for(int i = 1;i<11;i++){
        v.push_back(i);
    }
    vector<int> v2(v.begin(), v.end());
    vector<int> v3(10,1);
    
//    vector<int>::iterator pBegin = v.begin();
//    cout<<*pBegin<<endl;
    printVector(v3);
    printVector(v3);
}

//vector赋值(符号重载)

//vector& operator+(const vector &vec){
//
//}

void test4(){
    vector<int> v;
    for(int i = 1;i<11;i++){
        v.push_back(i);
    }
    vector<int> v2 = v;
    printVector(v2);
}

//栈stack
void test5(){
    stack<int> s;
    s.push(1);
    s.push(2);
    s.push(3);
    s.push(4);
    while (!s.empty()) {
        cout<<"当前栈大小: "<<s.size()<<endl;
        cout<<"栈顶: "<<s.top()<<endl;
        s.pop(); //pop()不能被cout输出流接收，因为可能会反回void。所以也不能将pop()赋值给其他变量
        cout<<"弹出~"<<endl;
    }
    cout<<"当前栈大小: "<<s.size()<<endl;
}

//set降序
class Mysort{
public:
    //不是很懂
    bool operator()(int v1,int v2){
        return v1 > v2;
    }
};

void setPrint(set<int,Mysort> s){
    set<int>::iterator it = s.begin();
    while (it != s.end()) {
        cout<<*it<<endl;
        it++;
    };
}

void test6(){
    set<int,Mysort> s;
    s.insert(10);
    s.insert(100);
    s.insert(8);
    s.insert(99);
    
    for(auto it:s){
        cout<<"foreach迭代:"<<it<<endl;
    }
    
//    setPrint(s);
};

//友元和符号重载
ostream &operator<<(ostream& out, People& p){
    out << "name:" <<p.name << "age:" << p.age;
    return out;
}

void test7() {

    People p1("lee", 20);

    //p1对象中重载了左移符号，所以p1使用左移时会优先返回自定义重载
    cout << p1 << "hello world" << endl; //链式编程
}
